﻿using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;

namespace SIMcSDK
{
    public delegate void OnRegStateChanged(int accountId, int regState);

    public struct Profile
    {

        public string profile_name, profile_password, account, proxy, realm, registrar, password;
        public int ID;
        public bool remember;

        public Profile(string account, string proxy, string realm, string registrar, string password)
        {
            this.account = account;
            this.password = password;
            this.registrar = registrar;
            this.proxy = proxy;
            this.realm = realm;
            this.ID = 0;
            this.remember = false;
            this.profile_password = "";
            this.profile_name="";
        }
    }

    public struct Contact {
        public string uri, displayName;
        public int ID;
    }

    public class RegistrationControl
    {
        Profile profil;

        #region DLL declarations
        [DllImport("pjsipDll.dll")]
        private static extern int dll_init(int listenPort);
        [DllImport("pjsipDll.dll")]
        private static extern int dll_main();
        [DllImport("pjsipDll.dll")]
        private static extern int dll_shutdown();
        [DllImport("pjsipDll.dll")]
        private static extern int dll_registerAccount(string uri, string reguri, string domain, string username, string password, string proxy, bool isdefault);
        [DllImport("pjsipDll.dll")]
        private static extern int dll_removeAccounts();
        #endregion DLL declarations
       
        #region Callback declarations
        // Callback function registration declarations 
        // passing delegate to unmanaged code (.dll)
        [DllImport("pjsipDll.dll")]
        private static extern int onRegStateCallback(OnRegStateChanged cb);
             
        // Static declaration because of CallbackonCollectedDelegate exception!
        static OnRegStateChanged rsDel = new OnRegStateChanged(onRegStateChanged);

        public static event OnRegStateChanged RegStateChanged;

        #endregion Callback declarations

        #region Callbacks
        private static void onRegStateChanged(int accountId, int regState)
        {
            if (null != RegStateChanged) RegStateChanged(accountId, regState);
            return;
        }

        #endregion Callbacks

        #region Methods

        /// <summary>
        /// Static initializer. Call this method to set callbacks from SIP stack. 
        /// </summary>
        public static void initialize()
        {
            // assign callbacks
            onRegStateCallback(rsDel);           
        }

        public static int start()
        {
            int status = -1;

            int port = 5060;
            status = dll_init(port);
            if (status != 0) return status;

            status |= dll_main();
            return status;
        }

        public static int shutdown()
        {
            return dll_shutdown();
        }

        public static int registerAccount(string uri, string reguri, string domain, string username, string password, string proxy, bool isdefault) { 
            return dll_registerAccount(uri, reguri, domain, username, password, proxy, isdefault);
        }

        public int registerAccounts()
        {
            return registerAccounts(false);
        }

        public int registerAccounts(bool renew)
        {
            //if (!IsInitialized) return -1;

            if (renew == true)
            {
                dll_removeAccounts();
            }
            int accId = 0;
            for (int i = 0; i < 1; i++)
            {
                //IAccount acc = Config.getAccount(i);
                // check if accounts available
                //if (null == acc) return -1;

                // reset account state
                //CallManager.setAccountState(i, 0);
                //BaseAccountStateChanged(i, 0);

                //if (acc.Id.Length > 0)
                //{
                //if (acc.HostName == "0") continue;
                /*-------------------------------
                    string displayName = TB_account.Text;
                    // Publish do not work if display name in uri 
                    string uri = "sip:" +TB_account.Text + "@" + TB_registrar.Text;
                    //string uri = "sip:" + Manager.getId(i) + "@" + Manager.getAddress(i) + "";
                    string reguri = "sip:"+ TB_registrar.Text; // +":" + CCallManager.getInstance().SipProxyPort;

                    string domain = TB_realm.Text;
                    string username = TB_account.Text;
                    string password = TB_pass.Text;
                    string proxy = TB_proxy.Text;
              
                    int ci = dll_registerAccount(uri, reguri, domain, username, password, proxy, true);
                    MessageBox.Show("Registracia: " + ci);
                    // todo:::check if accId corresponds to account index!!!
                    //}
                 -------------------------------------------*/

                string uri = "sip:" + profil.account;
                if (profil.account.IndexOf("@") < 0)
                {
                    uri += "@" + profil.registrar;
                }
                string reguri = "sip:" + profil.registrar;
                // check transport - if TCP add transport=TCP
                //reguri = pjsipStackProxy.Instance.SetTransport(i, reguri);

                string domain = profil.realm;
                string username = profil.account;
                string password = profil.password;
                string proxy = "";
                if (profil.proxy.Length > 0)
                {
                    proxy = "sip:" + profil.proxy;
                }
                //MessageBox.Show(uri);
                accId = dll_registerAccount(uri, reguri, domain, username, password, proxy, true);

            }


            return 1;
        }

        public static int removeAccounts()
        {
            return dll_removeAccounts();
        }
        #endregion Methods

    }
}
